<template>
	<div>
		<div class="bottom_option">
			<!-- <el-button type="danger" @click="openPreview">预览</el-button> -->
			<el-button type="primary" @click="submit">提交页面</el-button>
		</div>
		<section class="decoration-edit">
			<div class="l">
				<div class="title" style="margin-top: 10px">组件区</div>
				<text class="decoration_label" style="margin-top: 10px">基础组件</text>
				<ul @dragstart="dragStart" @dragend="dragEnd">
					<li v-for="(val, key, index) in typeList" :draggable="true" :data-type="key" :key="index + 1">
						<span
							class="icon"
							:style="{
								background: 'url(' + val.icon + ')',
								backgroundSize: '30px 30px',
								backgroundRepeat: 'no-repeat',
							}"
						/>
						<p>{{ val.name }}</p>
					</li>
				</ul>

				<div class="divider"></div>
				<text class="decoration_label" style="margin-top: 20px">引流入口</text>
				<ul @dragstart="dragStart" @dragend="dragEnd">
					<li v-for="(val, key, index) in marketingList" :draggable="true" :data-type="key" :key="index + 1">
						<span
							class="icon"
							:style="{
								background: 'url(' + val.icon + ')',
								backgroundSize: '30px 30px',
								backgroundRepeat: 'no-repeat',
							}"
						/>
						<p>{{ val.name }}</p>
					</li>
				</ul>
			</div>

			<div style="display: flex; flex-direction: column">
				<section class="c" ref="ref_capture" v-loading="submitLoading">
					<!-- header 不可拖拽 -->

					<div class="top-nav" :style="{ backgroundColor: infoBack, color: infoColor }">
						<div class="top_nav_hover" @click="selectType(0)">
							<img :src="topNavBlack" />
							<span class="tit">{{ infoTitle }}</span>
						</div>

						<div class="top_sreach top_nav_hover">
							<el-icon>
								<Search />
							</el-icon>
							<text style="margin-left: 3px">请输入关键字</text>
						</div>
					</div>

					<div ref="viewContent">
						<Draggable v-model="view" id="content_v" class="view-content" @drop="drog" @dragover="dragOver" animation="300">
							<template #item="{ element, index }">
								<div v-if="index > 0" :data-index="index" class="item" @click="selectType(index, element)">
									<template v-if="element.status && element.status == 2">
										<div class="wait drag_type_item" v-if="typeList[element.type]">{{ typeList[element.type].name }}</div>
										<div class="wait drag_type_item" v-if="marketingList[element.type]">{{ marketingList[element.type].name }}</div>
									</template>
									<template v-else>
										<div v-if="element.type != 'tabbarCom'">
											<component
												v-if="typeList[element.type]"
												:is="typeList[element.type].com"
												:data="element"
												:className="className[element.tabType]"
											></component>
											<component v-else :is="marketingList[element.type].com" :data="element" :className="className[element.tabType]"></component>
										</div>
									</template>

									<el-icon class="el-icon-error" @click="deleteItem($event, index)">
										<CircleCloseFilled />
									</el-icon>
								</div>
							</template>
						</Draggable>
					</div>
					<!-- 底部导航栏 -->
					<div class="bottom-tabber" @click="selectTabbar()">
						<Tabbar :data="tabbarData.data" />
					</div>
				</section>
			</div>

			<div class="r">
				<section v-show="isRight" style="background-color: white; height: 80vh; padding-top: 10px" class="option_right">
					<div class="title">操作区</div>
					<EditForm :data="props" :isRight="isRight" @submit="editSubmit" @openSort="openSort"></EditForm>
				</section>
			</div>
		</section>

		<viewSort :open="isOpenSort" :data="rightSortArr" @handleClose="closeSort" @submit="editSubmit"></viewSort>
	</div>
</template>

<script setup lang="ts" name="loginIndex">
import { onMounted, ref, nextTick, toRaw, watch } from 'vue';
import { NextLoading } from '/@/utils/loading';
import html2canvas from 'html2canvas';
import Draggable from 'vuedraggable';
import axios from 'axios';
import { Session } from '/@/utils/storage';
import { ElMessage, ElMessageBox } from 'element-plus';
import { useRoute, useRouter } from 'vue-router';

import { addOrEdit, addOrEditSite } from '/@/api/api';
//所有组件的编辑
import EditForm from '/@/components/buildPage/Edit/index.vue';
//商品
import Product from '/@/components/buildPage/View/Product.vue';
//图片
import Images from '/@/components/buildPage/View/Images.vue';
//图文导航
import QuickLink from '/@/components/buildPage/View/QuickLink.vue';
//搜索
import Sreach from '/@/components/buildPage/View/Sreach.vue';
//轮播图
import Banner from '/@/components/buildPage/View/Banner.vue';
//焦点广告
import FocusAdvertising from '/@/components/buildPage/View/focus.vue';
//氛围跑马灯
import Atmosphere from '/@/components/buildPage/View/Atmosphere.vue';
//调整顺序
import viewSort from '/@/components/viewSort/index.vue';
// 底部导航栏
import Tabbar from '/@/components/buildPage/View/Tabbar.vue';
// 文本
import Text from '/@/components/buildPage/View/Text.vue';

// 图标
import topNavBlack from '/@/assets/images/topNavBlack.png';
import iconFocusadvertising from '/@/assets/icon_focusadvertising.png';
import iconAtmosphere from '/@/assets/icon_atmosphere.png';
import iconPicture from '/@/assets/icon_picture.png';
import iconBanner from '/@/assets/icon_banner.png';
import iconGoods from '/@/assets/icon_goods.png';
import iconQuicklink from '/@/assets/icon_quicklink.png';
import iconText from '/@/assets/icon_text.png';

//dialog
import preview from './dialog/preview.vue';
import SubItem from '/@/layout/navMenu/subItem.vue';

const isOpenSort = ref(false);
const rightSortArr = ref([]);
const router = useRouter();
const typeAll = ref({});
const route = useRoute();
const ref_capture = ref();
const viewContent = ref();
const previewShow = ref(false);

//流量入口
const marketingList = ref({
	focusAdvertising: {
		name: '焦点广告',
		icon: iconFocusadvertising,
		com: FocusAdvertising,
	},
	atmosphere: {
		name: '跑马灯',
		icon: iconAtmosphere,
		com: Atmosphere,
	},
});

//基础组件
const typeList = ref({
	banner: {
		name: '轮播图',
		icon: iconBanner,
		com: Banner,
	},
	product: {
		name: '商品推荐',
		icon: iconGoods,
		com: Product,
	},

	quickLink: {
		name: '图文导航',
		icon: iconQuicklink,
		com: QuickLink,
	},
	text: {
		name: '文本',
		icon: iconText,
		com: Text,
	},
	images: {
		name: '图片',
		icon: iconPicture,
		com: Images,
	},
});

// 用于计算拖动模板的数量
const count = ref({
	focusAdvertising: 0,
	atmosphere: 0,
	images: 0,
	banner: 0,
	product: 0,
	quickLink: 0,
	text: 0,
});

const tabbarData = ref({
	type: 'tabbarCom',
	title: '底部导航栏',
	index: 1,
	data: [
		{
			title: '首页',
			textColor: '#000',
			icon: '',
			activeIcon: '',
			link: '',
			isDelete: false,
		},
		{
			title: '个人中心',
			textColor: '#000',
			icon: '',
			activeIcon: '',
			link: '',
			isDelete: false,
		},
	],
});

const view = ref([
	{
		type: 'info',
		title: '页面标题',
		// index: 0,
	},
]);
const className = ref({
	1: 'one',
	2: 'two',
	3: 'three',
});

const isRight = ref(false);
const props = ref({});
const type = ref();
const index = ref(null);
const isPush = ref(false);
const info = ref(view.value[0]);
const infoTitle = ref('预览区');
const infoBack = ref('');
const infoColor = ref('');
var tId = null;
var tname = null;

watch(
	() => isOpenSort.value,
	(val) => {
		isRight.value = !val;
	}
);

// 页面加载时
onMounted(() => {
	NextLoading.done();
	initPage();
});

//是否是site用户进来的装修
const isSite = ref(false);
//进来时初始化数据
function initPage() {
	if (toRaw(route).query.value.site && toRaw(route).query.value.site == 1) {
		isSite.value = true;
	}

	let lastPageItem = toRaw(route).query.value;
	if (lastPageItem.pageJson) {
		let pageJson = JSON.parse(lastPageItem.pageJson);
		view.value = pageJson;
		tId = lastPageItem.id;
		tname = lastPageItem.name;

		view.value.forEach((item, index) => {
			if (item.index) {
				count.value[item.type] = item.index;
			} else {
				count.value[item.type] = 0;
			}

			if (item.type == 'tabbarCom') {
				tabbarData.value.data = item.data;
			}
		});

		initTitleInfo(view.value[0]);
	}
}

function initTitleInfo(data: any) {
	infoTitle.value = data.title;
	infoBack.value = data.backgroundColor;
	infoColor.value = data.color;
}
function selectTabbar() {
	isRight.value = false;
	props.value = tabbarData.value;
	nextTick(() => (isRight.value = true));
}

// 切换视图组件
function selectType(index, element) {
	if (element && element.type && element.type == 'atmosphere') {
		return;
	}
	isRight.value = false;
	props.value = view.value[index];
	// console.log('props.value', props.value)
	nextTick(() => (isRight.value = true));
}

function deleteItem(e, index) {
	e.preventDefault();
	e.stopPropagation();
	view.value.splice(index, 1);
	isRight.value = false;
	props.value = {};
}
// 拖拽类型
function dragStart(e) {
	type.value = e.target.dataset.type;
}

// 已放置到指定位置
function drog(e) {
	if (!type.value) {
		// 内容拖拽
		return;
	}

	e.preventDefault();
	e.stopPropagation();
	count.value[view.value[index.value].type] = count.value[view.value[index.value].type] + 1;
	view.value[index.value].index = count.value[view.value[index.value].type];
	dragEnd(e);
}
// 结束拖拽
function dragEnd(e) {
	delete view.value[index.value].status;
	isPush.value = false;
	type.value = null;
}

// 移动中
function dragOver(e) {
	if (!type.value) {
		// 内容拖拽
		return;
	}
	e.preventDefault();
	e.stopPropagation();
	let className = e.target.className;
	let name = className !== 'view-content' ? 'item' : 'view-content';

	const defaultData = {
		type: type.value, // 组件类型
		status: 2, // 默认状态
		data: [], // 数据
		options: {}, // 选项操作
		index: 0,
	};

	if (name == 'view-content') {
		if (!isPush.value) {
			index.value = view.value.length;
			isPush.value = true;
			view.value.push(defaultData);
		}
	} else if (name == 'item') {
		let target = e.target;
		let [y, h, curIndex] = [e.offsetY, target.offsetHeight, target.dataset.index];
		let direction = y < h / 2;

		if (!isPush.value) {
			// Push to Top or Bottom
			if (direction) {
				if (curIndex == 0) {
					view.value.unshift(defaultData);
				} else {
					view.value.splice(curIndex, 0, defaultData);
				}
			} else {
				curIndex = +curIndex + 1;
				view.value.splice(curIndex, 0, defaultData);
			}
		} else {
			// Moving
			if (direction) {
				var i = curIndex == 0 ? 0 : curIndex - 1;
				var result = view.value[i].status == 2;
			} else {
				var i = +curIndex + 1;
				var result = view.value.length > i && view.value[i].status == 2;
			}

			if (result) return;

			const temp = view.value.splice(index.value, 1);
			view.value.splice(curIndex, 0, temp[0]);
		}
		index.value = curIndex;
		isPush.value = true;
	}
}

function makeAction(item, form) {
	item.actionDetail = form.actionDetail;
	item.actionType = form.actionType;
	item.miniPage = form.miniPage;
}

//上传预览图
async function uploadPreview1(form: any) {
	let { code, data } = await handleUploadPreview();
	if (code == 200) {
		ElMessageBox.prompt('请输入模版名称', 'Tip', {
			confirmButtonText: 'OK',
			cancelButtonText: 'Cancel',
			inputValue: tname,
		})
			.then(({ value }) => {
				if (isSite.value) {
					addOrEditSite({
						id: tId,
						imgUrl: data.fileUrl,
						name: value,
						page: JSON.stringify(form),
					}).then((res1) => {
						submitLoading.value = false;

						if (res1.code == 200) {
							ElMessage.success('保存成功');
							router.go(-1);
						}
					});
				} else {
					//	提交装修页面
					addOrEdit({
						id: tId,
						imgUrl: data.fileUrl,
						name: value,
						page: JSON.stringify(form),
					}).then((res1) => {
						submitLoading.value = false;
						if (res1.code == 200) {
							ElMessage.success('保存成功');
							router.go(-1);
						}
					});
				}
			})
			.catch((e) => {
				submitLoading.value = false;
			});
	}
}

//截图整屏预览并上传
function handleUploadPreview() {
	const formData = new FormData();
	const file = dataURLtoBlob(base64img.value, new Date() + '.jpg');
	formData.append('file', file);
	formData.append('fileCode', 'IMG');

	return axios
		.post(import.meta.env.VITE_API_URL + 'common/upload', formData, {
			headers: {
				'auth-token': `${Session.get('token')}`,
			},
		})
		.then((res) => {
			return res.data;
		})
		.catch((error) => {
			submitLoading.value = false;

			console.error('上传失败：', error);
		});
}

//上传图片
const base64img = ref<any>();
function dataURLtoBlob(dataurl, name) {
	var arr = dataurl.split(','),
		mime = arr[0].match(/:(.*?);/)[1],
		bstr = atob(arr[1]),
		n = bstr.length,
		u8arr = new Uint8Array(n);
	while (n--) {
		u8arr[n] = bstr.charCodeAt(n);
	}
	return new File([u8arr], name, {
		type: mime,
	});
}

//打开预览dialog
function openPreview() {
	previewShow.value = true;

	typeAll.value = Object.assign({}, marketingList.value, typeList.value);
}

function previewHandleClose() {
	previewShow.value = false;
}

//打开调整顺序侧边栏
function openSort(sortArr) {
	isOpenSort.value = true;
	rightSortArr.value = sortArr;
}

function closeSort() {
	isOpenSort.value = false;
}

function editSubmit(form) {
	//为了排序完之后同步right数据
	props.value = form;
	if (form.type == 'info') {
		infoBack.value = form.backgroundColor;
		infoColor.value = form.color;
		infoTitle.value = form.title;
	}

	if (form.type === 'banner' || form.type == 'images') {
		view.value.forEach((item) => {
			if (item.type == form.type && item.index == form.index) {
				item.data = form.data;
			}
		});
	}

	if (form.type === 'quickLink') {
		view.value.forEach((item) => {
			if (item.type == 'quickLink' && item.index == form.index) {
				item.data = form;
			}
		});
	}

	if (form.type === 'focusAdvertising') {
		view.value.forEach((item) => {
			if (item.type == 'focusAdvertising' && item.index == form.index) {
				item.data = form;
			}
		});
	}

	if (form.type === 'text') {
		view.value.forEach((item) => {
			if (item.type == 'text' && item.index == form.index) {
				console.log('🚀 ~ file: index.vue:559 ~ view.value.forEach ~  item.index:', item.index);

				item.data = form.data;
				makeAction(item, form);
			}
		});
	}

	if (form.type === 'tabbarCom') {
		tabbarData.value.data = form.data;
	}
}

/**
 * 最终提交json格式数据
 */
const submitLoading = ref(false);
function submit() {
	// JSON 转换会丢失 formData
	const form = JSON.parse(JSON.stringify(view.value));

	let hadTabbar = false;
	form.forEach((item) => {
		if (item.type == 'tabbarCom') {
			Object.assign(item, tabbarData.value);
			hadTabbar = true;
		}
	});

	if (!hadTabbar) {
		form.push(tabbarData.value);
	}

	submitLoading.value = true;
	nextTick(() => {
		document.getElementById('content_v').scrollTo({
			top: 0,
		});

		html2canvas(ref_capture.value, {
			useCORS: true,
			allowTaint: true,
			scale: 0.5,
		}).then((canvas) => {
			const base64 = canvas.toDataURL().replace(/^data:image\/(png|jpg);base64,/, '');
			base64img.value = `data:image/png;base64,${base64}`;

			uploadPreview1(form);
		});
	});
}
</script>

<style lang="scss">
.divider {
	height: 1px;
	background-color: #f6f6f6;
	margin-left: 30px;
	margin-right: 30px;
	margin-top: 10px;
}

.decoration_label {
	font-size: 12px;
	color: #bebebe;
	margin-left: 30px;
}

.decoration-edit {
	display: flex;
	// align-items: center;
	justify-content: space-between;
	padding: 10px 0;
	background: #f7f8f9;
	height: calc(100vh - 150px);
	position: relative;

	.title {
		margin-left: 15px;
		font-size: 14px;
		font-weight: 500;
		margin-bottom: 10px;
	}

	.l,
	.r {
		width: 340px;
		height: 80vh;
		// padding: 15px 0;
		// background: #fff;
		transition: all 0.5s;
	}

	.r {
		// overflow-y: scroll;
	}

	.l {
		display: flex;
		flex-direction: column;
		background: #fff;
		box-shadow: 0 0 10px rgba($color: #000000, $alpha: 0.1);

		ul {
			margin: 0;
			padding: 0;

			li {
				width: 80px;
				height: 80px;
				display: flex;
				justify-content: center;
				align-items: center;
				flex-direction: column;
				cursor: default;
				list-style: none;
				font-size: 14px;
				color: #666;
				float: left;
				margin: 0 10px;
				border-radius: 6px;
				transition: all 0.3s;
				cursor: pointer;

				&:hover {
					background: #efefef;
				}

				span {
					display: block;
					font-size: 40px;
					margin-bottom: 8px;
					color: #999;
				}

				p {
					display: block;
					margin: 0;
					font-size: 12px;
				}
			}
		}
	}

	.c {
		width: auto;
		max-width: 400px;
		position: relative;

		.top_nav_hover {
			position: relative;

			& * {
				pointer-events: none;
			}

			&:hover {
				// transform: scale(0.95);
				border-radius: 10px;
				overflow: hidden;
				box-shadow: 0 0 10px #afafaf;
			}
		}

		.top-nav {
			position: absolute;
			top: 0;
			background: #fff;
			z-index: 999;
			// transition: all 0.3s;
			display: flex;
			flex-direction: column;

			// & * {
			// 	pointer-events: none;
			// }
			// &:hover {
			// 	// transform: scale(0.95);
			// 	border-radius: 10px;
			// 	overflow: hidden;
			// 	box-shadow: 0 0 10px #afafaf;
			// }
			.tit {
				position: absolute;
				left: 50%;
				bottom: 10px;
				transform: translateX(-50%);
			}

			img {
				max-width: 100%;
				image-rendering: -moz-crisp-edges;
				image-rendering: -o-crisp-edges;
				image-rendering: -webkit-optimize-contrast;
				image-rendering: crisp-edges;
				-ms-interpolation-mode: nearest-neighbor;
			}
		}

		.view-content {
			width: 400px;
			height: 650px;
			background: #f5f5f5;
			overflow-y: auto;
			overflow-x: hidden;
			padding-top: 122px;
			box-shadow: 0 2px 6px #ccc;
			padding-bottom: 75px;

			&::-webkit-scrollbar {
				width: 6px;
			}

			&::-webkit-scrollbar-thumb {
				background: #dbdbdb;
			}

			&::-webkit-scrollbar-track {
				background: #f6f6f6;
			}

			.item {
				// transition: all 0.3s;
				// margin-top: 10px;
				// margin-left: 10px;
				// margin-right: 10px;
				// background: #fff;
				&:hover {
					transform: scale(0.98);
					border-radius: 10px;
					box-shadow: 0 0 10px #afafaf;

					.el-icon-error {
						display: block;
					}
				}

				div {
					pointer-events: none;
				}

				.wait {
					background: #deedff;
					height: 35px;
					text-align: center;
					line-height: 35px;
					font-size: 12px;
					color: #666;
				}

				.el-icon-error {
					position: absolute;
					right: -10px;
					top: -6px;
					color: red;
					font-size: 25px;
					cursor: pointer;
					display: none;
					z-index: 9999;
				}
			}
		}

		.bottom-tabber {
			width: 100%;
			height: 60px;
			background-color: #fff;
			position: absolute;
			// margin-bottom: -60px;
			bottom: 0;
			border-top: 1px solid #e4e7ed;
			// box-shadow: 0 0 10px #afafaf;

			&:hover {
				transform: scale(0.98);
				border-radius: 10px;
				box-shadow: 0 0 10px #afafaf;

				.el-icon-error {
					display: block;
				}
			}
		}
	}

	.submit-btn {
		position: absolute;
		bottom: 30px;
		left: 50%;
		transform: translateX(-50%);
	}
}

.icon {
	width: 30px;
	height: 30px;
}

.top_sreach {
	height: 30px;
	margin-top: 10px;
	margin-left: 10px;
	margin-right: 10px;
	margin-bottom: 10px;
	padding-left: 10px;
	background-color: #f5f5f5;
	border-radius: 100px;
	display: flex;
	align-items: center;
	color: #ccc;
}

.bottom_option {
	width: 100%;
	height: 60px;
	background-color: white;
	position: absolute;
	bottom: 0;
	right: 0;
	display: flex;
	z-index: 1000;
	justify-content: flex-end;
	align-items: center;
	box-shadow: 0 0 5px rgba($color: #000000, $alpha: 0.2);
	padding-right: 10px;
}

.option_right {
	box-shadow: 0 0 10px rgba($color: #000000, $alpha: 0.1);
	animation-name: rightIn;
	animation-duration: 0.5s;
	animation-timing-function: cubic-bezier(0, 0, 0, 0.9);
}

@keyframes rightIn {
	0% {
		transform: translate(100%, 0);
	}

	100% {
		transform: translate(0, 0);
	}
}
</style>
